﻿using SindelsStarship;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading;

class TheStarship
{

    static Encoding encoding = Encoding.UTF8;

    static SpaceShip drunckenRider;

    const int MaxHeight = 39;
    const int MaxWidth = 59;
    const int PlayField = 37;
    const int InfoFieldStartColumn = 40;
    static int steps = 0;
    static int enemiesPause = 7;
    const string statisticsFile = @"../../statistics.txt";
    const string caveInput = @"../../Cave.txt";
    static string mainTheme = @"../../Popcorn_song.wav";
    static string introTheme = @"../../swtheme.wav";
    static string lordVader = @"../../swvader03.wav";
    static string force = @"../../force.wav";
    static string shotgun = @"../../saberdown.wav";
    static bool sound = true;
    static bool isBounseGenerated = false;
    static bool isEndKeyPress = false;

    static char[, ,] cave;
    static bool[,] visited;
    static int wCave;
    static int hCave;
    static int dCave;

    static SoundPlayer sp;
    static SoundPlayer shotSound;
    static WMPLib.WindowsMediaPlayer player;

    static List<Enemy> enemies = new List<Enemy>();
    static List<Shots> shots = new List<Shots>();
    static List<Enemy> bonuses = new List<Enemy>();

    static Random rand = new Random();

    //statistic info fields
    static string playerName = null;
    static int catchBonus = 0;
    static int enemyDown = 0;
    static int level = 1;
    static int lives = 3; //count of lives of the player
    static int speed = 100;

    // List with game controls info
    static List<string> gameControls = new List<string>();

    static void Main(string[] args)
    {
        //if press "end" button exit game
        //if press "space" make shot
        //if press arrows move in position
        //if press "P" pause the game

        System.Console.OutputEncoding = encoding;

        //List with game controls info !IMPORTANT - Add new lines with Add() method
        gameControls.Add("Exit game  - End");
        gameControls.Add("Make shots - Space");
        gameControls.Add("Move ship  - Arrows");
        gameControls.Add("Pause game - P");
        gameControls.Add("Mute       - M");

        Console.BufferHeight = Console.WindowHeight = MaxHeight;
        Console.BufferWidth = Console.WindowWidth = MaxWidth;

        PlayIntroTheme();
        StartScreen();
        InputPlayerInfo();
        PlaySound();
        drunckenRider = new SpaceShip(PlayField);
        drunckenRider.GoToStartPosition();
        shotSound = new SoundPlayer(shotgun);

        // Game engine
        while (lives > 0 && (!isEndKeyPress))
        {
            DrawPlayFieldVerticalLine();
            ShowInfo();
            if (steps % enemiesPause == 0)
            {
                UpdateEnemies();
                GenerateEnemy();
                UpdateBonuses();
                GenerateBonuses();
                steps = 0;
            }

            UpdateShots();
            ShipsActivity();
            DrawEnemies();
            DrawBonuses();
            DrawShots();
            DrawShip(drunckenRider);
            CheckSpaceShipHit();
            CheckEnemyHit();
            CheckBonusHit();

            ChangeLevel();

            steps++;
            Thread.Sleep(speed);
            Console.Clear();
        }

        sp.Stop();
        player.controls.stop();

        PlayGameOver();

        int point = CalculateScore();
        SaveInfo(playerName, point);
        PrintHiScore();

        GameOverInfo();

    }


    //strat labirint code
    private static void InitCave()
    {
        char[] spliters = { ' ' };
        try
        {
            using (StreamReader sr = new StreamReader(caveInput, encoding))
            {
                string[] sizes = sr.ReadLine().Split(spliters, StringSplitOptions.RemoveEmptyEntries);
                wCave = int.Parse(sizes[0]);
                hCave = int.Parse(sizes[1]);
                dCave = int.Parse(sizes[2]);
                cave = new char[wCave, hCave, dCave];
                for (int h = 0; h < hCave; h++)
                {
                    for (int d = 0; d < dCave; d++)
                    {
                        string line = sr.ReadLine();
                        for (int w = 0; w < wCave; w++)
                        {
                            if (line[w] == ' ')
                            {
                                cave[w, h, d] = '.';
                            }
                            else
                            {
                                cave[w, h, d] = line[w];
                            }

                        }
                    }
                }
            }
        }
        catch (IOException exp)
        {
            Console.WriteLine("Errpr: ", exp.Message);
        }
    }

    private static void PrintCave(int randomStage, int artefacts)
    {
        Console.Clear();

        Console.SetCursorPosition(14, 8);
        Console.WriteLine("Drunken rider go to Nabby caves");

        for (int d = 0; d < dCave; d++)
        {
            Console.SetCursorPosition(12, 10 + d);
            for (int w = 0; w < wCave; w++)
            {
                //Console.SetCursorPosition(w, d);
                if (cave[w, randomStage, d] == 'Y' || cave[w, randomStage, d] == '+')
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                }
                else if (cave[w, randomStage, d] == '@')
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                }
                else if (cave[w, randomStage, d] == '#')
                {
                    Console.ForegroundColor = ConsoleColor.Blue;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                Console.Write("{0,3}", cave[w, randomStage, d]);
            }
        }
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.SetCursorPosition(14, 20);
        Console.WriteLine("Find artefacts: {0}", artefacts);
    }

    private static bool HasPosibleMove(int w, int h, int d, bool[,] visited)
    {
        bool result = false;
        bool findPosibleMove = false;
        for (int i = w - 1; i < w + 2; i++)
        {
            if (i < 1 || i > wCave - 2)
            {
                continue;
            }
            for (int j = d - 1; j < d + 2; j++)
            {
                if (j < 1 || j > dCave - 2)
                {
                    continue;
                }
                else
                {
                    if (cave[i, h, j] == '.' || cave[i, h, j] == '@')
                    {
                        if (!visited[i, j])
                        {
                            //Console.WriteLine(i+" "+j+"pos");
                            findPosibleMove = true;
                            result = true;
                            break;
                        }
                    }
                }
            }
            if (findPosibleMove)
            {
                break;
            }
        }
        return result;
    }

    private static bool CanMove(int w, int h, int d, bool[,] visited, int direction, int[] corectW, int[] corectD)
    {
        bool result = ((cave[w + corectW[direction], h, d + corectD[direction]] == '.'
            || cave[w + corectW[direction], h, d + corectD[direction]] == '@')
            && (!visited[w + corectW[direction], d + corectD[direction]]));
        Console.WriteLine(result);
        return result;
    }

    private static int GoWalkInCave(int h)
    {
        InitCave();
        visited = new bool[wCave, dCave];
        int collectArtefacts = 0;
        int direction = rand.Next(0, 8);
        int w = rand.Next(1, wCave);
        int d = rand.Next(1, dCave);
        int[] corectW = { 1, 1, 0, -1, -1, -1, 0, 1 };
        int[] corectD = { 0, -1, -1, -1, 0, 1, 1, 1 };

        while (!(cave[w, h, d] == '.' || cave[w, h, d] == '@'))
        {
            w = rand.Next(1, wCave);
            d = rand.Next(1, dCave);
        }

        while (HasPosibleMove(w, h, d, visited))
        {
            while (!CanMove(w, h, d, visited, direction, corectW, corectD))
            {
                direction = rand.Next(0, 8);
            }
            cave[w, h, d] = '+';
            visited[w, d] = true;
            w += corectW[direction];
            d += corectD[direction];
            if (cave[w, h, d] == '@')
            {
                collectArtefacts++;
            }
            cave[w, h, d] = 'Y';
            visited[w, d] = true;
            PrintCave(h, collectArtefacts);
            Thread.Sleep(400);
        }
        Console.ForegroundColor = ConsoleColor.Green;
        Console.SetCursorPosition(14, 22);
        Console.WriteLine("Press any kye to contionue");
        return collectArtefacts;
    }
    //labirint code end



    private static void PlayGameOver()
    {
        sp = new SoundPlayer(force);
        sp.Play();
    }

    private static void PlayIntroTheme()
    {
        sp = new SoundPlayer(introTheme);
        sp.PlayLooping();
    }

    //TODO Start Screen - DONE
    private static void StartScreen()
    {
        Console.Clear();
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine();
        Console.WriteLine("                     ##### #   # #####");
        Console.WriteLine("                       #   #   # #    ");
        Console.WriteLine("                       #   ##### ###  ");
        Console.WriteLine("                       #   #   # #    ");
        Console.WriteLine("                       #   #   # #####");
        Console.WriteLine("                    -------------------");
        Console.WriteLine();
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("         ###   ####  #   # #   # #   # ##### #   #");
        Console.WriteLine("         #  #  #   # #   # ##  # #  #  #     ##  #");
        Console.WriteLine("         #   # ####  #   # # # # ###   ###   # # #");
        Console.WriteLine("         #  #  #  #  #   # #  ## #  #  #     #  ##");
        Console.WriteLine("         ###   #   # ####  #   # #   # ##### #   #");
        Console.WriteLine("        -------------------------------------------");
        Console.WriteLine();
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine("                ####  ###  ###   ##### #### ");
        Console.WriteLine("                #   #  #   #  #  #     #   #");
        Console.WriteLine("                ####   #   #   # ###   #### ");
        Console.WriteLine("                #  #   #   #  #  #     #  # ");
        Console.WriteLine("                #   # ###  ###   ##### #   #");
        Console.WriteLine("           -------------------------------------");
        Console.WriteLine();
        Console.SetCursorPosition(Console.WindowWidth - 41, Console.WindowHeight - 14);
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Press any key to start...");
        Console.ReadKey();
        Console.ForegroundColor = ConsoleColor.Gray;
        Console.Clear();
    }

    //TODO Generating bonuses
    private static void GenerateBonuses()
    {
        if (!isBounseGenerated)
        {
            int posX = rand.Next(0, PlayField - 2);
            int posY = 0;
            if (enemyDown % 19 == 0 && enemyDown != 0)
            {
                Enemy bonuse = new Enemy(posX, posY);
                bonuse.Color = ConsoleColor.Red;
                bonuse.Bonus = BonusType.Bonuses.Live;
                bonuses.Add(bonuse);
                //enemyDown++;
            }
            else if (enemyDown % 9 == 0 && enemyDown != 0)
            {
                Enemy bonuse = new Enemy(posX, posY);
                bonuse.Bonus = BonusType.Bonuses.SpeedUp;
                bonuse.Color = ConsoleColor.Green;
                bonuses.Add(bonuse);
            }

            else if (enemyDown % 11 == 0 && enemyDown != 0)
            {
                Enemy bonuse = new Enemy(posX, posY);
                bonuse.Bonus = BonusType.Bonuses.SpeedDown;
                bonuse.Color = ConsoleColor.DarkMagenta;
                bonuses.Add(bonuse);
            }
            else if (enemyDown % 21 == 0 && enemyDown != 0)
            {
                Enemy bonuse = new Enemy(posX, posY);
                bonuse.Bonus = BonusType.Bonuses.InstantKillAll;
                bonuse.Color = ConsoleColor.White;
                bonuses.Add(bonuse);
            }
            if (enemyDown % 29 == 0 && enemyDown != 0)
            {
                Enemy bonuse = new Enemy(posX, posY);
                bonuse.Color = ConsoleColor.Magenta;
                bonuse.Bonus = BonusType.Bonuses.GoToCave;
                bonuses.Add(bonuse);
            }
            isBounseGenerated = true;
        }
    }     //can add new type of bonus

    //TODO updating Bonuses - Done
    private static void UpdateBonuses() //move bonuses
    {
        foreach (var bonus in bonuses)
        {
            bonus.PosY++;
            if (bonus.PosY > Console.WindowHeight - 1)
            {
                bonus.IsPosInPlayField = false;
            }
        }
        bonuses.RemoveAll(f => f.IsPosInPlayField == false);
    }

    //TODO colisians with bonuses - Done
    private static void CheckBonusHit()
    {
        for (int bonuse = 0; bonuse < bonuses.Count; bonuse++)
        {
            for (int shot = 0; shot < shots.Count; shot++)
            {
                if ((shots[shot].PosX == bonuses[bonuse].PosX ||
                    shots[shot].PosX - 1 == bonuses[bonuse].PosX ||
                    shots[shot].PosX - 2 == bonuses[bonuse].PosX) &&
                    (shots[shot].PosY == bonuses[bonuse].PosY ||
                     shots[shot].PosY - 1 == bonuses[bonuse].PosY))
                {
                    if (bonuses[bonuse].Bonus == BonusType.Bonuses.Live)
                    {
                        lives++;
                    }
                    else if (bonuses[bonuse].Bonus == BonusType.Bonuses.SpeedUp)
                    {
                        if (speed - 1 > 50)
                        {
                            speed--;
                        }
                        else
                        {
                            speed = 50;
                        }
                    }
                    else if (bonuses[bonuse].Bonus == BonusType.Bonuses.SpeedDown)
                    {
                        if (speed + 1 > 200)
                        {
                            speed = 200;
                        }
                        else
                        {
                            speed++;
                        }
                    }
                    else if (bonuses[bonuse].Bonus == BonusType.Bonuses.InstantKillAll)
                    {
                        enemyDown += enemies.Count;
                        enemyDown += bonuses.Count - 1;
                        enemies.ForEach(f => f.IsPosInPlayField = false);
                        bonuses.ForEach(f => f.IsPosInPlayField = false);
                    }
                    else if (bonuses[bonuse].Bonus == BonusType.Bonuses.GoToCave)
                    {
                        while (Console.KeyAvailable)
                        {
                            Console.ReadKey();
                        }
                        int caveLevel = rand.Next(0, 3);
                        lives += GoWalkInCave(caveLevel);
                        drunckenRider.GoToStartPosition();
                        shots.ForEach(f => f.IsPosInPlayField = false);
                    }
                    bonuses[bonuse].IsPosInPlayField = false;
                    shots[shot].IsPosInPlayField = false;
                    isBounseGenerated = false;
                    enemyDown++;
                }
            }
        }



    }

    //TODO draw all bonuses
    private static void DrawBonuses()
    {
        ConsoleColor currentColor = Console.ForegroundColor;
        foreach (var bonus in bonuses)
        {
            Console.SetCursorPosition(bonus.PosX, bonus.PosY);
            Console.ForegroundColor = bonus.Color;
            Console.Write(bonus.Symbol);
        }
        Console.ForegroundColor = currentColor;
    }

    //TODO score calculation - done
    private static int CalculateScore()
    {
        return ((enemyDown * level) + (catchBonus * (level * 100)));
    }

    //TODO changing levels depending of the kills - CHECK
    private static void ChangeLevel()
    {
        if (enemyDown % 70 == 0 && enemyDown != 0)
        {
            level++;
            enemyDown++;

            //reset enemy, shots, bonuses
            enemies.ForEach(f => f.IsPosInPlayField = false);
            bonuses.ForEach(f => f.IsPosInPlayField = false);
            shots.ForEach(f => f.IsPosInPlayField = false);
            drunckenRider.GoToStartPosition();


            if (enemiesPause - 1 > 0)
            {
                enemiesPause--;
            }

            if (enemyDown % 300 == 0 && speed - 5 > 0)
            {
                speed -= 5;
            }
        }


    }

    //TODO background sound - DONE
    private static void PlaySound()
    {
        sp.Stop();
        string fullPath = Path.GetFullPath(mainTheme);
        player = new WMPLib.WindowsMediaPlayer();
        player.URL = fullPath;
        player.controls.play();
        player.settings.setMode("loop", true);
    }

    //TODO colisians with enemy and shots - DONE
    private static void CheckEnemyHit()
    {
        for (int enemy = 0; enemy < enemies.Count; enemy++)
        {
            for (int shot = 0; shot < shots.Count; shot++)
            {
                if ((shots[shot].PosX == enemies[enemy].PosX ||
                    shots[shot].PosX - 1 == enemies[enemy].PosX ||
                    shots[shot].PosX - 2 == enemies[enemy].PosX) &&
                    (shots[shot].PosY == enemies[enemy].PosY ||
                     shots[shot].PosY - 1 == enemies[enemy].PosY))
                {
                    enemies[enemy].IsPosInPlayField = false;
                    shots[shot].IsPosInPlayField = false;
                    isBounseGenerated = false;
                    enemyDown++;
                }
            }
        }

        RemoveEnemiesAndShotsOutOfBoundaries();
    }

    //TODO remove shots and enemyies - DONE
    public static void RemoveEnemiesAndShotsOutOfBoundaries()
    {
        enemies.RemoveAll(f => f.IsPosInPlayField == false);
        shots.RemoveAll(f => f.IsPosInPlayField == false);
    }

    //TODO game over -Done
    private static void GameOverInfo()
    {
        Console.SetCursorPosition(20, 10);
        Console.Write("GAME OVER");
        Console.SetCursorPosition(0, Console.WindowHeight - 1);
        Console.ReadKey();
    }

    //TODO colisians with SpaceShip -Done
    private static void CheckSpaceShipHit()
    {
        bool isShipHit = false;
        foreach (var enemy in enemies)
        {
            if ((enemy.PosY == drunckenRider.PosY && (Math.Abs(enemy.PosX - drunckenRider.PosX) < 3))
                || (enemy.PosY == drunckenRider.PosY - 1 && (Math.Abs(enemy.PosX - drunckenRider.PosX) < 2)))
            {
                isShipHit = true;
                enemy.IsPosInPlayField = true;
                enemyDown++;
                break;
            }
        }

        foreach (var bonuse in bonuses)
        {
            if ((bonuse.PosY == drunckenRider.PosY && (Math.Abs(bonuse.PosX - drunckenRider.PosX) < 3))
                || (bonuse.PosY == drunckenRider.PosY - 1 && (Math.Abs(bonuse.PosX - drunckenRider.PosX) < 2)))
            {
                if (bonuse.Bonus != BonusType.Bonuses.Live)
                {
                    isShipHit = true;
                    bonuse.IsPosInPlayField = true;
                    enemyDown++;
                }
                else
                {
                    bonuse.IsPosInPlayField = true;
                    enemyDown++;
                }
                break;
            }
        }

        if (isShipHit)
        {
            lives--;
            speed = 100;
            bonuses.Clear();
            enemies.Clear();
            shots.Clear();
            drunckenRider.GoToStartPosition();
            Console.Clear();

            if (lives == 0)
            {
                isEndKeyPress = true;
            }
        }
    }

    //TODO show current info -Done
    private static void ShowInfo()
    {
        int speedOffset = 200;
        ConsoleColor currentColor = Console.ForegroundColor;

        //Name Info
        Console.SetCursorPosition(InfoFieldStartColumn, 0);
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Write("# # # # # # # # #");
        Console.SetCursorPosition(InfoFieldStartColumn + 1, 1);
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("DRUNKEN RIDER'S  ");
        Console.SetCursorPosition(InfoFieldStartColumn + 7, 2);
        Console.Write("NAME");
        Console.SetCursorPosition(InfoFieldStartColumn, 3);
        Console.Write("-----------------");
        Console.SetCursorPosition(InfoFieldStartColumn + 4, 4);
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.Write(playerName);
        Console.SetCursorPosition(InfoFieldStartColumn, 5);
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Write("# # # # # # # # #");

        //ScoreInfo
        Console.SetCursorPosition(InfoFieldStartColumn + 3, 6);
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("ENEMIES DEAD");
        Console.SetCursorPosition(InfoFieldStartColumn, 7);
        Console.Write("-----------------");
        Console.SetCursorPosition(InfoFieldStartColumn + 8, 8);
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.Write(enemyDown);
        Console.SetCursorPosition(InfoFieldStartColumn, 9);
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Write("# # # # # # # # #");

        //LevelInfo
        Console.SetCursorPosition(InfoFieldStartColumn + 6, 10);
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("LEVEL");
        Console.SetCursorPosition(InfoFieldStartColumn, 11);
        Console.Write("-----------------");
        Console.SetCursorPosition(InfoFieldStartColumn + 8, 12);
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.Write(level);
        Console.SetCursorPosition(InfoFieldStartColumn, 13);
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Write("# # # # # # # # #");

        //SpeedInfo
        Console.SetCursorPosition(InfoFieldStartColumn + 6, 14);
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("SPEED");
        Console.SetCursorPosition(InfoFieldStartColumn, 15);
        Console.Write("-----------------");
        Console.SetCursorPosition(InfoFieldStartColumn + 7, 16);
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.Write(speedOffset - speed);
        Console.SetCursorPosition(InfoFieldStartColumn, 17);
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Write("# # # # # # # # #");

        //bonus info
        Console.SetCursorPosition(InfoFieldStartColumn + 6, 18);
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("BONUSES");
        Console.SetCursorPosition(InfoFieldStartColumn, 19);
        Console.Write("-----------------");
        Console.SetCursorPosition(InfoFieldStartColumn, 20);
        if (bonuses.Count > 0)
        {
            Console.ForegroundColor = ConsoleColor.Red;
        }
        else
        {
            Console.ForegroundColor = ConsoleColor.DarkRed;
        }
        int lineCorect = 0;
        foreach (var bonuse in bonuses)
        {
            Console.ForegroundColor = bonuse.Color;
            Console.SetCursorPosition(InfoFieldStartColumn, 20 + lineCorect);
            Console.Write(bonuse.Bonus);
            lineCorect++;
        }

        // game controls
        Console.SetCursorPosition(InfoFieldStartColumn, 28);
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("GAME CONTROLS");
        Console.SetCursorPosition(InfoFieldStartColumn, 29);
        Console.Write(new String('-', 18));
        int nextCursorPosition = 30;
        Console.ForegroundColor = ConsoleColor.Yellow;
        foreach (var control in gameControls)
        {
            Console.SetCursorPosition(InfoFieldStartColumn, nextCursorPosition);
            Console.Write(control);
            nextCursorPosition++;
        }





        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.SetCursorPosition(InfoFieldStartColumn, Console.WindowHeight - 4);
        Console.WriteLine("        UPs");
        Console.SetCursorPosition(InfoFieldStartColumn, Console.WindowHeight - 3);
        Console.WriteLine(new string('-', 18));


        //Lives info
        Console.ForegroundColor = ConsoleColor.DarkRed;
        Console.SetCursorPosition(InfoFieldStartColumn, Console.WindowHeight - 2);
        if (lives > 5)
        {
            for (int live = 0; live < lives; live++)
            {
                if (live % 9 == 0)
                {
                    Console.SetCursorPosition(InfoFieldStartColumn, Console.WindowHeight - 1);
                }
                Console.Write("\u2665 ");
            }
        }
        else
        {
            Console.Write(string.Concat(Enumerable.Repeat("\u2665 ", lives)));
        }

        Console.ForegroundColor = currentColor;
    }

    //TODO write to file "score.txt" statistics about game -> done
    private static void SaveInfo(string name, int curPoints)
    {
        try
        {
            StringBuilder score = new StringBuilder();

            List<Score> hiScore = new List<Score>();

            if (!File.Exists("score.txt"))// create file and save first ever score
            {
                score.Append("1. ");
                score.Append(name);
                score.Append(" - ");
                score.Append(curPoints);
                score.Append("\r\n");
                File.AppendAllText("score.txt", score.ToString());
                score.Clear();
            }
            else//read all last score results
            {
                string[] allResults = File.ReadAllLines("score.txt");
                File.Delete("score.txt");
                for (int i = 0; i < allResults.Length; i++)
                {
                    int spaceNum = allResults[i].LastIndexOf(' ');
                    int thisPoints = int.Parse(allResults[i].Substring(spaceNum + 1));
                    string thisName = allResults[i].Substring(3, (spaceNum - 5));

                    hiScore.Add(new Score(thisName, thisPoints));
                }

                hiScore.Add(new Score(name, curPoints));//add current player score result
                hiScore.Sort();//sort on hi points basis

                int bestPlayerNumber = 1;// count player position in HiScore and save it
                foreach (var item in hiScore)
                {
                    score.Append(bestPlayerNumber);
                    score.Append(". ");
                    score.Append(item.ToString());
                    score.Append("\r\n");
                    File.AppendAllText("score.txt", score.ToString());
                    score.Clear();

                    if (bestPlayerNumber == 10)//count top 10 players
                    {
                        break;
                    }
                    bestPlayerNumber++;
                }
            }
        }
        catch (Exception)
        {
            Console.SetCursorPosition(10, 10);
            Console.WriteLine("Sorry something got wrong please start again !"); ;
        }
    }

    private static void PrintHiScore()//prints HiScores
    {
        try
        {
            using (StreamReader read = new StreamReader("score.txt"))
            {
                int i = 3;
                string readOnLine = read.ReadLine();
                while (readOnLine != null)
                {
                    Console.SetCursorPosition(16, 10 + i);
                    Console.WriteLine(readOnLine);
                    readOnLine = read.ReadLine();
                    i++;
                }
            }
        }
        catch (FileNotFoundException)//print when no file found /if delite the file while saving/
        {
            Console.SetCursorPosition(10, 10);
            Console.WriteLine("No games played, so there is no HiScore to see!!!");
            Console.WriteLine("=========== Please start game again ! ===========");
        }
    }


    //TODO something interesting


    //TODO implement UpdateShots() method - Done
    private static void UpdateShots()
    {
        foreach (var shot in shots)
        {
            shot.PosY--;
            if (shot.PosY < 0)
            {
                shot.IsPosInPlayField = false;
            }
        }
        RemoveShotsOutOfBoundaries();
    }

    //TODO implement RemoveShotsOutOfBoundaries() method - Done
    private static void RemoveShotsOutOfBoundaries()
    {
        shots.RemoveAll(f => f.IsPosInPlayField == false);
    }

    //TODO implement DrawShots() method - Done
    private static void DrawShots()
    {
        ConsoleColor currentColor = Console.ForegroundColor;
        foreach (var shot in shots)
        {
            Console.SetCursorPosition(shot.PosX, shot.PosY);
            Console.ForegroundColor = shot.Color;
            Console.Write(shot.Symbol);
        }
        Console.ForegroundColor = currentColor;
    }

    //TODO implement DrawEnemy(...) method - Done
    private static void DrawEnemies()
    {
        ConsoleColor currentColor = Console.ForegroundColor;
        foreach (var enemy in enemies)
        {
            Console.SetCursorPosition(enemy.PosX, enemy.PosY);
            Console.ForegroundColor = enemy.Color;
            Console.Write(enemy.Symbol);
        }
        Console.ForegroundColor = currentColor;
    }

    //TODO implement GenerateEnemy() method - Done
    private static void GenerateEnemy()
    {
        int posX = rand.Next(0, PlayField - 2);//Enemy symbol.length=3 ^V^
        int posY = 0;
        Enemy enemy = new Enemy(posX, posY);
        enemies.Add(enemy);
    }

    //TODO implement UpdateEnemies() method - Done
    private static void UpdateEnemies() // moves enemy downside
    {
        //moves one row down
        //marks enemy to remove
        //if we found enemy that is out of the boundaries we have to remove it
        foreach (var enemy in enemies)
        {
            enemy.PosY++;
            if (enemy.PosY > Console.WindowHeight - 1)
            {
                enemy.IsPosInPlayField = false;
            }
        }
        RemoveEnemiesOutOfBoundaries();
    }

    //TODO implement RemoveEnemiesOutOfBoundaries() method - Done
    public static void RemoveEnemiesOutOfBoundaries()
    {
        enemies.RemoveAll(f => f.IsPosInPlayField == false);
    }

    static void DrawShip(SpaceShip drunckenRider)
    {
        //TODO write code for droawing ship
        ConsoleColor currentColor = Console.ForegroundColor;
        Console.ForegroundColor = drunckenRider.Color;
        Console.SetCursorPosition(drunckenRider.PosX + 1, drunckenRider.PosY - 1);
        Console.Write(drunckenRider.FrontShip);
        Console.SetCursorPosition(drunckenRider.PosX, drunckenRider.PosY);
        Console.Write(drunckenRider.BackShip);
        Console.ForegroundColor = currentColor;
    }

    //TODO implement MoveShip() method - Done
    static void ShipsActivity()
    {

        while (Console.KeyAvailable)
        {
            // implement key controls for Ship movement
            var pressKey = Console.ReadKey();
            if (pressKey.Key == ConsoleKey.LeftArrow)
            {
                drunckenRider.MoveLeft();
                drunckenRider.MoveLeft();
            }
            else if (pressKey.Key == ConsoleKey.RightArrow)
            {
                drunckenRider.MoveRight();
                drunckenRider.MoveRight();
            }
            else if (pressKey.Key == ConsoleKey.UpArrow)
            {
                drunckenRider.MoveUp();
                drunckenRider.MoveUp();
            }
            else if (pressKey.Key == ConsoleKey.DownArrow)
            {
                drunckenRider.MoveDown();
                drunckenRider.MoveDown();

            }
            else if (pressKey.Key == ConsoleKey.Spacebar)
            {
                Shots shot = new Shots(drunckenRider.PosX + 1, drunckenRider.PosY - 2);
                shots.Add(shot);
                if (sound)
                {
                    shotSound.Play();
                }
            }
            else if (pressKey.Key == ConsoleKey.End)
            {
                isEndKeyPress = true;
            }
            else if (pressKey.Key == ConsoleKey.P)
            {
                player.controls.pause();
                LordVaderTalks();
                Console.SetCursorPosition(12, 14);
                Console.Write("PAUSE");
                Console.SetCursorPosition(4, 15);
                Console.Write("Press key to continue...");
                Console.ReadKey();
                player.controls.play();
                //PlaySound();

            }
            else if (pressKey.Key == ConsoleKey.M)
            {
                //sp.Stop();
                if (sound)
                {
                    player.controls.pause();
                    sound = false;
                }
                else
                {
                    player.controls.play();
                    sound = true;
                }
            }
        }
    }

    private static void LordVaderTalks()
    {
        sp = new SoundPlayer(lordVader);
        sp.Play();
    }

    //TODO implement DrawPlayFieldVerticalLine() method - Done
    static void DrawPlayFieldVerticalLine()
    {
        for (int i = 0; i < Console.WindowHeight; i++)
        {
            Console.SetCursorPosition(PlayField, i);
            Console.Write("#");
        }
    }

    //TODO implement InputPlayerInfo() method - Done
    private static void InputPlayerInfo()
    {
        Console.SetCursorPosition(18, 13);
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("DRUNKEN RIDER'S NAME:");

        Console.SetCursorPosition(17, 14);
        Console.Write("-----------------------");
        Console.SetCursorPosition(25, 15);
        Console.ForegroundColor = ConsoleColor.Red;

        playerName = Console.ReadLine();
        if (playerName == "")
        {
            Console.SetCursorPosition(13, 17);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write("You must enter a name!!!");
            InputPlayerInfo();
        }



        Console.Clear();
    }
}




